/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    gpio.c
  * @brief   This file provides code for the configuration
  *          of all used GPIO pins.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* 如果需要去掉打印，只需要去掉下边两行即可 */
#define LOG_TAG          "gpio"
#include <elog.h>

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "bsp_gpio.h"
#include "delay.h"
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/*----------------------------------------------------------------------------*/
/* Configure GPIO                                                             */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, LCD_D0_Pin|LCD_D1_Pin|LCD_D2_Pin|LCD_D3_Pin
                          |LCD_D4_Pin|LCD_D5_Pin|LCD_D6_Pin|LCD_D7_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, LCD_RST_Pin|LCD_CS_Pin|LCD_WR_Pin|LCD_A0_Pin
                          |LCD_RD_Pin|LCD_BL_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, LED3_Pin|LED4_Pin|LED5_Pin|LED6_Pin
                          |LED1_Pin|LED2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : PCPin PCPin PCPin PCPin
                           PCPin PCPin PCPin PCPin */
  GPIO_InitStruct.Pin = LCD_D0_Pin|LCD_D1_Pin|LCD_D2_Pin|LCD_D3_Pin
                          |LCD_D4_Pin|LCD_D5_Pin|LCD_D6_Pin|LCD_D7_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PAPin PAPin PAPin PAPin
                           PAPin PAPin */
  GPIO_InitStruct.Pin = LCD_RST_Pin|LCD_CS_Pin|LCD_WR_Pin|LCD_A0_Pin
                          |LCD_RD_Pin|LCD_BL_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PBPin PBPin PBPin PBPin */
  GPIO_InitStruct.Pin = KEY1_Pin|KEY2_Pin|KEY3_Pin|KEY4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PBPin PBPin PBPin PBPin
                           PBPin PBPin */
  GPIO_InitStruct.Pin = LED3_Pin|LED4_Pin|LED5_Pin|LED6_Pin
                          |LED1_Pin|LED2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  #if 0
  HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);

  HAL_NVIC_SetPriority(EXTI2_3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);
  #endif
}

/* USER CODE BEGIN 2 */
/* LED灯驱动 ******************************************************************/
void drv_led1_status_set(u8 sta)
{
    if(sta == LED_OFF)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
    }
    if(sta == LED_ON)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
    }
}
led_obj LED1 = {
    .sta = LED_OFF,
    .setsta = drv_led1_status_set,
};

void drv_led2_status_set(u8 sta)
{
    if(sta == LED_OFF)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
    }
    if(sta == LED_ON)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
    }
}
led_obj LED2 = {
    .sta = LED_OFF,
    .setsta = drv_led2_status_set,
};

void drv_led3_status_set(u8 sta)
{
    if(sta == LED_OFF)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
    }
    if(sta == LED_ON)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
    }
}
led_obj LED3 = {
    .sta = LED_OFF,
    .setsta = drv_led3_status_set,
};

void drv_led4_status_set(u8 sta)
{
    if(sta == LED_OFF)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED4_Pin, GPIO_PIN_SET);
    }
    if(sta == LED_ON)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED4_Pin, GPIO_PIN_RESET);
    }
}
led_obj LED4 = {
    .sta = LED_OFF,
    .setsta = drv_led4_status_set,
};

void drv_led5_status_set(u8 sta)
{
    if(sta == LED_OFF)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED5_Pin, GPIO_PIN_SET);
    }
    if(sta == LED_ON)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED5_Pin, GPIO_PIN_RESET);
    }
}
led_obj LED5 = {
    .sta = LED_OFF,
    .setsta = drv_led5_status_set,
};

void drv_led6_status_set(u8 sta)
{
    if(sta == LED_OFF)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED6_Pin, GPIO_PIN_SET);
    }
    if(sta == LED_ON)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED6_Pin, GPIO_PIN_RESET);
    }
}
led_obj LED6 = {
    .sta = LED_OFF,
    .setsta = drv_led6_status_set,
};

void bsp_led_set(led_obj *led, u8 sta)
{
    led->setsta(sta);
}

/* 按键驱动 ******************************************************************/
_drv_key drv_key1 = {
        .pin = KEY1_Pin,
        .port = KEY1_GPIO_Port,
        .old_sta = KEY_DEFAULT_VALUE,
};
_drv_key drv_key2 = {
        .pin = KEY2_Pin,
        .port = KEY2_GPIO_Port,
        .old_sta = KEY_DEFAULT_VALUE,
};
_drv_key drv_key3 = {
        .pin = KEY3_Pin,
        .port = KEY3_GPIO_Port,
        .old_sta = KEY_DEFAULT_VALUE,
};
_drv_key drv_key4 = {
        .pin = KEY4_Pin,
        .port = KEY4_GPIO_Port,
        .old_sta = KEY_DEFAULT_VALUE,
};

key_obj key[4] = {
    {.id = 0x01},
    {.id = 0x0A},
    {.id = 0X14},
    {.id = 0X1E},
};


void dev_key_open(void)
{
    key[0].obj = (_drv_key *)&drv_key1;
    key[1].obj = (_drv_key *)&drv_key2;
    key[2].obj = (_drv_key *)&drv_key3;
    key[3].obj = (_drv_key *)&drv_key4;
}

void dev_key_close(void)
{
    key[0].obj = NULL;
    key[1].obj = NULL;
    key[3].obj = NULL;
    key[4].obj = NULL;
}

u8 dev_keyvalue_get(key_obj* key)
{
    return key->obj->keyvalue;
}

void dev_key_callback_register(key_obj* key, keycallback callback_func)
{
    key->callback = callback_func;
}

u8 dev_key_scan(void)
{
    static u16 tmp = 0;
#ifdef KEY_USE_POLL
    delay_ms(1); // 默认延时1ms
#endif /* KEY_USE_POLL */
    for(u8 inx = 0; inx < 4; inx++)
    {
        /* 循环采样16次，都是相同的数值，则认为按键状态稳定 */
        //key[inx].obj->new_sta = KEY_OBJ_READ(key[inx]); // 读取GPIO状态
        tmp = KEY_PIN_READ(key[inx].obj->port, key[inx].obj->pin);
        key[inx].obj->new_sta = ((key[inx].obj->new_sta)<<1) | tmp;
        
        if(key[inx].obj->new_sta == KEY_PRESS_VALUE && \
            key[inx].obj->old_sta == KEY_DEFAULT_VALUE) /* 判断按键按下 */
        {
            key[inx].obj->old_sta = key[inx].obj->new_sta;
            key[inx].obj->keyvalue = KEY_PRESS;
            log_d("KEY[%d] is press\r", key[inx].id);
            
            key[inx].callback(key[inx].obj->keyvalue); /* 按键1回调函数 */
        }
        
        if(key[inx].obj->new_sta == KEY_DEFAULT_VALUE && \
            key[inx].obj->old_sta == KEY_PRESS_VALUE) /* 判断按键弹起 */
        {
            key[inx].obj->old_sta = key[inx].obj->new_sta;
            key[inx].obj->keyvalue = KEY_UP;
            log_d("KEY[%d] is upspring\r", key[inx].id);
            //key1->callback(key1->obj->keyvalue); /* 按键1回调函数 */
        }
    }
}

u8 key_callback(u8 keyvalue)
{
    log_i("key value:%02x\r", keyvalue);
}

void key_scan_test_init(void)
{
    dev_key_open();
    dev_key_callback_register(&key[0], key_callback);
    dev_key_callback_register(&key[1], key_callback);
    dev_key_callback_register(&key[2], key_callback);
    dev_key_callback_register(&key[3], key_callback);
}

void key_scan_test(void)
{
    dev_key_scan();
}

/* USER CODE END 2 */
